package com.yiyuplatform.service.websocket.impl;

import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.yiyuplatform.form.ConsultMsgForm;
import com.yiyuplatform.service.websocket.WebSocketService;
import io.netty.handler.codec.http.HttpHeaders;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * \* Created with IntelliJ IDEA.
 * \* User: 大龙
 * \* Date: 2021/11/6
 * \* Time: 20:10
 * \* Description:
 * \
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WebSocketServiceImpl implements WebSocketService {
    //用户池
    private static final Map<UUID, SocketIOClient> CLIENT_MAP = new ConcurrentHashMap<>();
    private final SocketIOServer socketIOServer;

    /**
     * @Description: 服务器启动时会调用一次
     */
    @PostConstruct
    @Override
    public void autoStart() {
        log.info("WebWocket服务器启动");
        // 建立连接监听事件 - Token校验
        socketIOServer.addConnectListener(client -> {
            System.out.println(client.toString());
            String token = getClientToken(client, "token");
            if (checkToken(token)) {
                log.info("check success");
                CLIENT_MAP.put(client.getSessionId(), client);
            } else {
                client.disconnect();
            }
        });
        // 断开连接监听事件 - token移除
        socketIOServer.addDisconnectListener(client -> {
            CLIENT_MAP.remove(client.getSessionId());
            client.disconnect();
            log.info("移除client:{}", client.getSessionId());
        });
        socketIOServer.start();
        log.info("start finish");
    }

    @Override
    /**
     * @Description: token校验，登录态
     * @Param: [token] 用户登录客户端时，分配的token
     * @return: boolean
     */
    public boolean checkToken(String token) {

        log.info("检查token是否有效:{}", token);
        /**
         * 到Redis数据库中检查Token列表
         * code here
         * */
        return true;
    }

    @Override
    /**
     * @Description: 获取Header里的Token
     * @Param: client
     * @Param: key
     * @return: java.lang.String
     */
    public String getClientToken(SocketIOClient client, String key) {
//        HttpHeaders httpHeaders = client.getHandshakeData().getHttpHeaders();
//        return httpHeaders.get(key);
        key=client.getHandshakeData().getSingleUrlParam("token");
        return key;
    }

    @PreDestroy
    @Override
    public void onDestroy() {
        if (socketIOServer != null) {
            socketIOServer.stop();
        }
    }

    @Override
    public int sendMsg(Object demo) {
        /**
         * code here
         * */
        CLIENT_MAP.forEach((key, value) -> {
            value.sendEvent("server_event", demo);
            log.info("发送数据成功:{}", key);
        });
        return CLIENT_MAP.size();
    }

    @Override
    public int sendConsultMsg(ConsultMsgForm consultMsgForm) {
        /**
         * code here
         * */
        return 0;
    }
}
